/*
 * @Description: IM聊天模块
 * @Author: Kerwin
 * @Date: 2024-08-14 10:27:27
 * @LastEditTime: 2025-04-11 15:40:44
 * @LastEditors:  Please set LastEditors
 */
import { defineStore } from 'pinia'
import RongIMLib, {
  HongBaoMessage,
  ProductMessage,
  PinTuanMessage
} from '@/packageD/common/rongCloud/im_init'
import { CONTENT_TYPES } from '@/packageD/common/rongCloud/msgType'
import {
  ConversationType,
  IAReceivedConversation,
  IUserProfileInfo
} from '@rongcloud/imlib-next'
import { UserInfo } from './userStore'
import { Message } from '../../packageD/common/rongCloud/msgType'
import { nextTick } from 'vue'
import { IAReceivedMessage, MessageType } from '@rongcloud/imlib-next'

interface GroupUser {
  userId: number
  friendCircleId: number
  type: number
  user: UserInfo
  settingDisableSendMsg: boolean
  settingRefusedLocation: boolean
  settingRefusedNotify: boolean
}
interface IAReceivedConversationWithBaseInfo extends IAReceivedConversation {
  name: string
  portraitUri: string
  showAction: boolean
}
let lifeData: {
  userinfo?: { id: number; userId: number }
  latestConversationList?: IAReceivedConversationWithBaseInfo[]
  messagelist?: any
  conversationlist?: IAReceivedConversation[]
} = {}
try {
  // 尝试获取本地是否存在lifeData变量，第一次启动应用时是不存在的
  lifeData = uni.getStorageSync('lifeData')
} catch (e) {}
// 需要永久存储，且下次应用启动需要取出的，在state中的变量名
const saveStateKeys = ['userinfo', 'latestConversationList', 'messagelist']
// 保存变量到本地存储中
const saveLifeData = (key: string, value: any, storageKey: string) => {
  // 判断变量名是否在需要存储的数组中
  if (saveStateKeys.indexOf(key) !== -1) {
    // 获取本地存储的lifeData对象，将变量添加到对象中
    let tmp = uni.getStorageSync(storageKey)
    // 第一次打开APP，不存在lifeData变量，故放一个{}空对象
    tmp = tmp || {}
    tmp[key] = value
    // 执行这一步后，所有需要存储的变量，都挂载在本地的lifeData对象中
    uni.setStorageSync(storageKey, tmp)
  }
}
/**
 * 群成员列表
 *  key: 群targetId
 */
const useStore = defineStore('ry', {
  state: (): {
    userinfo: { id: number; userId: number }
    totalUnreadCount: { home: number; list: number }
    friendsUnreadCount: number
    latestConversationList: IAReceivedConversationWithBaseInfo[]
    messagelist: any
    allGroupUsers: { [key: string]: GroupUser[] }
    friendslist: any[]
    grouplist: any[]
    addfriendslist: any[]
    conversationList: IAReceivedConversation[]
    currentConversationHistoryMessageList: IAReceivedMessage[]
  } => ({
    userinfo: lifeData.userinfo ?? { id: 0, userId: 0 },
    totalUnreadCount: { home: 0, list: 0 },
    friendsUnreadCount: 0,
    latestConversationList: [],
    messagelist: lifeData.messagelist ?? {},
    allGroupUsers: {},
    friendslist: [],
    grouplist: [],
    addfriendslist: [],
    conversationList: [],
    currentConversationHistoryMessageList: []
  }),
  actions: {
    $uStore(
      name: string,
      value: RongIMLib.IAReceivedConversation[],
      storageKey: string
    ) {
      // 判断是否多层级调用，state中为对象存在的情况，诸如user.info.score = 1
      const nameArr = name.split('.')
      let saveKey = ''
      const len = nameArr.length
      if (len >= 2) {
        let obj = this[nameArr[0]]
        for (let i = 1; i < len - 1; i++) {
          obj = obj[nameArr[i]]
        }
        obj[nameArr[len - 1]] = value
        saveKey = nameArr[0]
      } else {
        // 单层级变量，在state就是一个普通变量的情况
        this[name] = value
        saveKey = name
      }
      // 保存变量到本地，见顶部函数定义
      saveLifeData(saveKey, this[saveKey], storageKey)
    },
    // 建立链接
    connect(token: string): Promise<boolean> {
      return new Promise((resolve, reject) => {
        RongIMLib.connect(token)
          .then((res) => {
            if (res.code === RongIMLib.ErrorCode.SUCCESS) {
              this.userinfo = { ...res.data, id: res?.data.userId }
              console.log('链接成功, 链接用户为: ', res.data)
              this.getConversationList()
              resolve(true)
            } else {
              console.warn('链接失败, code:', res)
            }
          })
          .catch((error) => {
            uni.showToast({ title: '连接服务器失败', icon: 'none' })
            console.log('链接失败: ', error)
          })
      })
    },
    ScanAudio() {
      const innerAudioContext = uni.createInnerAudioContext()
      innerAudioContext.autoplay = true
      innerAudioContext.src =
        'https://image.blacksilverscore.com/App/77f3730f-9726-4946-8459-2a80df785ac5.mp3'
      innerAudioContext.play()
    },
    // 全局更新
    setvar(
      name: string,
      value: RongIMLib.IAReceivedConversation[],
      storageKey: string
    ) {
      this.$uStore(name, value, storageKey)
    },
    // 缓存消息
    setMessage(message: IAReceivedMessage, type: string, index?: number) {
      console.log('消息体==>', message, '\n', '操作==>', type)
      if (message.messageType === 'RC:RcCmd') {
        this.updateRecalledMsg(message)
        return
      }
      const { id } = this.userinfo
      if (!this.messagelist[id]) {
        this.messagelist[id] = {}
      }
      const messagelist = this.messagelist[id]
      if (!messagelist[message.targetId]) {
        messagelist[message.targetId] = []
      }
      let timer: NodeJS.Timeout | null = null
      if (type === 'add' && CONTENT_TYPES.includes(message.messageType)) {
        if (timer) {
          clearTimeout(timer)
          timer = null
        }
        timer = setTimeout(() => {
          this.ScanAudio()
          timer = null
        }, 300)
        messagelist[message.targetId].push(message)
        this.currentConversationHistoryMessageList.push(message)
      } else if (type === 'delete') {
        messagelist[message.targetId].splice(index, 1)
        this.currentConversationHistoryMessageList.splice(index, 1)
      } else if (type === 'update' && index !== undefined) {
        messagelist[message.targetId][index] = message
      }
      this.setvar(`messagelist.${this.userinfo.id}`, messagelist, 'lifeData')
    },
    // 缓存群成员
    setGroupUser(
      data: { targetId: number; userList?: GroupUser[]; user?: GroupUser },
      type: string,
      index?: number
    ) {
      const { targetId } = data
      if (!this.allGroupUsers[targetId]) {
        this.allGroupUsers[targetId] = []
      }
      switch (type) {
        case 'add':
          this.allGroupUsers[targetId].push(...(data.userList ?? []))
          break
        case 'delete':
          this.allGroupUsers[targetId].splice(!index ? 0 : index, 1)
          break
        case 'update':
          if (index !== undefined && data.user) {
            this.allGroupUsers[targetId][index] = data.user
          }
          break
      }
    },
    // 清除指定会话未读数
    clearMessagesUnreadStatus(
      targetId: string,
      conversationType: ConversationType
    ) {
      return new Promise((resolve, reject) => {
        RongIMLib?.clearMessagesUnreadStatus({
          conversationType,
          targetId
        }).then((res) => {
          if (res.code === 0) {
            // 清理成功
            resolve(res)
            // 发送多端同步未读数消息
            RongIMLib?.sendSyncReadStatusMessage(
              { conversationType, targetId },
              Date.now()
            )
          } else {
            console.log(res.code, res.msg)
            reject(res)
          }
        })
      })
    },
    // 删除会话
    delMessageList(uuid: any, type: ConversationType, id: any) {
      const conversation = RongIMLib.removeConversation({
        targetId: uuid,
        conversationType: type
      })
      conversation.then(() => console.log('删除会话成功'))
    },
    /**
     * @description: 构建消息
     * @return {*}
     * @author: Kerwin
     */
    buildMsg(data: {
      targetId?: any
      title?: string
      content?: any
      msgType: any
      imageUri?: string
      group?: any
      latitude?: any
      longitude?: any
      referMsg?: any
      totalCount?: number
      totalMoney?: number
      nickname?: string
      friendCircleRedPacketId?: number
      imageUrl?: string
      path?: string
      orderId?: any
      productId?: any
      shopId?: any
      sightUrl?: any
      size?: any
      duration?: any
      redPacketTypeName?: string // 红包类型名称
      avatar?: string
      options?: object
    }) {
      const {
        msgType,
        title,
        content,
        imageUri,
        latitude,
        longitude,
        referMsg,
        totalCount,
        nickname,
        friendCircleRedPacketId,
        totalMoney,
        imageUrl,
        path,
        orderId,
        productId,
        shopId,
        sightUrl,
        size,
        duration,
        redPacketTypeName,
        avatar,
        options
      } = data
      let message: RongIMLib.BaseMessage<any> | null = null
      switch (msgType) {
        case 1:
          message = new RongIMLib.TextMessage({ content })
          break
        case 2:
          message = new RongIMLib.ImageMessage({
            content, // 图片缩略图，应为 Base64 字符串，且不可超过 80KB
            imageUri // 图片的远程访问地址
          })
          break
        case 3:
          message = new RongIMLib.FileMessage({
            name: '',
            size: 1000,
            type: '',
            fileUrl: ''
          })
          break
        case 4:
          message = new RongIMLib.HQVoiceMessage({
            remoteUrl: '<aac 文件地址>',
            duration: 60
          })
          break
        case 5:
          message = new RongIMLib.SightMessage({
            sightUrl,
            content, // '<缩略图>'
            duration,
            size,
            name: title as string
          })
          break
        case 6:
          message = new RongIMLib.GIFMessage({
            gifDataSize: 30,
            remoteUrl: '<图片地址>',
            width: 300,
            height: 200
          })
          break
        case 7:
          message = new RongIMLib.ReferenceMessage({
            referMsgUserId: referMsg.senderUserId,
            referMsgUid: referMsg.messageUId,
            referMsg: {
              content: referMsg.content.content
            },
            content,
            objName: RongIMLib.MessageType.TEXT
          })
          break
        case 8:
        case MessageType.LOCATION:
          message = new RongIMLib.LocationMessage({
            latitude,
            longitude,
            poi: '',
            content
          })
          break
        case 9:
          message = new HongBaoMessage({
            title,
            content,
            totalCount,
            totalMoney,
            status: 1,
            nickname,
            redPacketTypeName,
            friendCircleRedPacketId,
            avatar,
            options
          })
          break
        case 10:
          message = new ProductMessage({
            title,
            content,
            imageUrl,
            path,
            productId,
            shopId
          })
          break
        case 11:
          message = new PinTuanMessage({
            title,
            content,
            imageUrl,
            path,
            orderId
          })
          break
        default:
          message = new RongIMLib.TextMessage({ content })
          break
      }
      return message
    },
    // 发送消息
    sendMessage(data: {
      targetId: any
      content: any
      msgType: any
      conversationType: ConversationType
      options?: object
      [key: string]: any
    }) {
      const { targetId, conversationType } = data
      const conversation = {
        targetId,
        conversationType: conversationType
      }
      const message = this.buildMsg(data)
      // 发送消息
      RongIMLib.sendMessage(conversation, message, data.options || {}).then(
        ({ code, data }) => {
          if (code === 0) {
            console.log('消息发送成功：', data)
            const { userId } = this.userinfo
            if (!this.messagelist[userId]) {
              this.messagelist[userId] = {}
            }
            if (!this.messagelist[userId][targetId]) {
              this.messagelist[userId][targetId] = []
            }
            const messagelist = this.messagelist[userId][targetId]
            messagelist.push(data)
            this.currentConversationHistoryMessageList.push(data)
            console.log(`messagelist.${userId}.${targetId}`)
            this.setvar(
              `messagelist.${userId}.${targetId}`,
              messagelist,
              'lifeData'
            )
          } else {
            console.log('消息发送失败：', code)
          }
        }
      )
    },
    // 撤回消息
    recallMessage(data: {
      targetId: any
      messageUId: any
      sentTime: any
      conversationType: any
    }) {
      const { targetId, messageUId, sentTime, conversationType } = data
      const conversation = {
        targetId,
        conversationType
      }
      return RongIMLib.recallMessage(conversation, {
        messageUId,
        sentTime
      })
    },
    // 更新撤回的消息
    updateRecalledMsg(message: RongIMLib.IAReceivedMessage) {
      const { content } = message
      const list = this.currentConversationHistoryMessageList
      const idx = list.findIndex(
        (item) => item.messageUId === content.messageUId
      )
      if (idx !== -1) {
        list.splice(idx, 1, message)
      }
    },
    /**
     * 更新消息扩展信息
     * @param message  - 要更新的消息对象
     * @param options  - 要更新的消息扩展信息
     */
    updateMessageExpansion(
      message: RongIMLib.IAReceivedMessage,
      options: { [key: string]: any }
    ) {
      RongIMLib.updateMessageExpansion(options, message).then((res) => {
        if (res.code === 0) {
          console.log(res, '更新成功')
        } else {
          console.log(res.code, res.msg)
        }
      })
    },
    // 获取会话列表
    getConversationList() {
      RongIMLib.getConversationList().then(
        ({ code, data: conversationList }) => {
          if (code === 0) {
            console.log('获取会话列表成功', conversationList)
            this.latestConversationList =conversationList as IAReceivedConversation[]
            console.log(this.latestConversationList)
          } else {
            console.log('获取会话列表失败: ')
          }
        }
      )
    },

    /**
     * 获取指定会话历史消息
     * @param targetId - 目标 ID
     * @param type - 会话类型
     */
    getHistoryMessages(targetId: string, type: ConversationType) {
      console.log('获取指定会话消息', targetId, type)
      const conversation = {
        conversationType: type,
        targetId: targetId
      }
      // 从当前时间开始向前查询
      const option: RongIMLib.GetHistoryMessageOption = {
        timestamp: 0,
        count: 20,
        order: 0
      }
      RongIMLib.getHistoryMessages(conversation, option).then((res: any) => {
        if (res.code === 0) {
          console.log('获取历史消息成功', res.data)
          this.currentConversationHistoryMessageList = res.data.list
        } else {
          console.log(res.code, res.msg,'获取历史消息失败')
        }
      })
    },
    /**
     * 获取指定会话第一条未读消息信息
     * @param targetId - 目标 ID
     * @param type
     */
    getFirstUnreadMessageInfo(targetId: string, type: ConversationType) {
      const conversation = {
        conversationType: RongIMLib.ConversationType.PRIVATE,
        targetId: targetId
      }
      RongIMLib.getFirstUnreadMessageInfo(conversation).then((res) => {
        if (res.code === 0) {
          console.log(res.data)
        } else {
          console.log(res.code, res.msg)
        }
      })
    },
    /**
     * 更新用户资料
     * @param data - 要更新的用户资料信息
     * @returns - 包含更新结果的 Promise 对象
     */
    async updateMyUserProfile(data: IUserProfileInfo) {
      const profile: IUserProfileInfo = {
        ...data,
        userId: this.userinfo.userId.toString()
      }
      const res = await RongIMLib.updateMyUserProfile(profile)
      console.log('更新用户资料结果：', res)
    },
    /**
     * 批量获取用户信息
     * @param userIds - 要获取的用户 ID 数组
     * @returns - 包含用户信息的 Promise 对象
     */

    getUserProfiles(userIds: string[]) {
      return RongIMLib.getUserProfiles(userIds)
    },
    /**
     *  
     * @param userIds - 要获取的用户 ID 数组
     * @returns - 包含用户信息的 Promise 对象
     */

    joinGroup(groupId: string) {
      return RongIMLib.joinGroup(groupId)
    },

    /**
     * 从会话列表中移除指定会话
     * @param targetId - 要移除的会话的目标 ID
     * @param conversationType - 要移除的会话的类型
     */
    removeConversation(targetId: string, conversationType: ConversationType,uState:boolean) {
    if(uState) {
      uni.showModal({
        title: '提示',
        content: '删除后，将清空所有消息记录',
        success: (res) => {
          if (res.confirm) {
            const conversation = {
              targetId,
              conversationType
            }
            RongIMLib.removeConversation(conversation).then((res) => {
              if (res.code === 0) {
                console.log('移除会话成功')
                this.latestConversationList.splice(
                  this.latestConversationList.findIndex(
                    (item) => item.targetId === targetId
                  ),
                  1
                )
              } else {
                console.log('移除会话失败：', res.code, res.msg)
              }
            })
          }
        }
      })
    } else{
      const conversation = {
        targetId,
        conversationType
      }
      RongIMLib.removeConversation(conversation).then((res) => {
        if (res.code === 0) {
          console.log('移除会话成功')
          this.latestConversationList.splice(
            this.latestConversationList.findIndex(
              (item) => item.targetId === targetId
            ),
            1
          )
        } else {
          console.log('移除会话失败：', res.code, res.msg)
        }
      })
    }

    },
    /**
     * 设置会话置顶
     */
    setConversationToTop(targetId: any, conversationType: any, isTop: boolean) {
      return RongIMLib.setConversationToTop(
        {
          conversationType,
          targetId
        },
        isTop
      )
    },
    /**
     * 更新会话
     */
    updateConversation(data: { conversationList: any }) {
      const { conversationList } = data
      if (!conversationList.length) return
      const _this = this
      conversationList.forEach(
        (c: { conversation: IAReceivedConversation }) => {
          const idx = _this.latestConversationList.findIndex(
            (item) => item.targetId === c.conversation.targetId
          )
          if (idx > -1) {
            _this.latestConversationList[idx] = {
              ..._this.latestConversationList[idx],
              ...c.conversation
            }
          } else {
            _this.latestConversationList.unshift(c.conversation)
          }
        }
      )
    }
  }
})

export default useStore
